If grep outputs the words themselves, why is the "next unless" part working?
In list context, grep will output the words, but in scalar context, (here forced by 'unless'), grep will return the number (0 1 2 ...) of times the condition it is testing is true.
In this code, if grep tests a word composed of unique letters, the regex test will fail and applying the negation (!), forms a double negative which is equal to true. Here grep returns 1, (or 2 or more depending how many words are made up of unique letters in @list).