I can shorten your 36 non-duplicate-letter attempt by 5 chars with:
# 1 2 3
#234567890123456789012345678901
grep/^(([@_])(?!.*\2))+$/x,<D>;
I think this trick might be applicable to your others as well...
Update: I'm still trying to grok your longer ones (re eval in golf... coool) and I'm uncovering some oddities:
qw(a d d)
ad
add
dad
qw(a d)
ad
add <= wrong... but 'dad' got correctly skipped... I think
add gets through because the 'd's are right
next to each other
Doubled letters (dd, tt, etc) are sneaking through... It looks like $n{'d'} needs to be temporarilly decremented when 'd' matches in the character class...
-Blake