I sugest doing it this way.

Code:
on @*:join:#:{
 var %max = $lines(badword.txt), %counter = 1
 while (%counter <= %max) {
    if ($read(badword.txt,nt,%counter) isin $nick) { kick $chan $nick Bad Nick! | return }
    inc %counter
  }
}


1st get a %MAX value to go to (total lines in the file), and also set a start value %COUNTER to count up to the %MAX

Check if COUNTER is less or equal to MAX and if so do the contents of the while loop
..Read the word on line number COUNTER of the file and if its in $nick, then kick the nick & RETURN (exits the event) [means u dont carry on]
..Otherwise just add one to COUNTER and repeat the while loop check

* the reason i would start at the begining of the file and work towards the end, is two fold, there is less disk access in reading the first lines of the file vs the last lines, so if the match is located near the start smaller disk access has occured, 2nd reason is more real world logic than fact, the more likely bad words well be in the file first, so its better to start from the front of the file, than the end.

* the reason i store the %MAX value, is becuase every time u do $lines(badword.txt) it must read the whole file to get the number of lines, so its much much better to do it once and store it than compare to it in the while loop.

* the last thing to note is the RETURN following the kick, there is no reason to continue through the rest of the file if the user was kicked.