Something like this?
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11116556
use warnings;
use Path::Tiny;
my $dictionary = path( '/usr/share/dict/words' );
my @tiles = qw( a a d r t s c );
my $string = 'f e ';
my $pat = join '', map "$_?", sort @tiles, $string =~ /\w/g;
my $tilepat = join '', map "$_?", sort @tiles;
my $letters = join '', @tiles, $string =~ /\w/g;
print "$pat\n$tilepat\n";
my @matches =
grep { ( join '', sort split // ) =~ /^$pat$/ }
$dictionary->slurp =~ /^[$letters]{2,}$/gm;
my @places;
($string =~ tr/ /./r) =~
/(?<!\w).{2,}(?!\w)(?{ push @places, $& })(*FAIL)/;
@places = grep /\w/, @places;
use Data::Dump 'dd'; dd \@places;
my @matches1 = extension(1);
print "@matches1\n\n";
my @matches2 = extension(2);
print "@matches2\n\n";
sub extension
{
my $id = shift;
my @found;
for my $placepat ( $id == 1 ? @places : map expand($_), @places )
{
for my $match ( @matches )
{
$match =~ /^$placepat$/ or next;
my $newtiles = $match & ($placepat =~ tr/.a-z/\xff\0/r);
(join '', sort $newtiles =~ /\w/g) =~ /^$tilepat$/ and
push @found, $match;
}
}
return @found;
}
sub expand
{
grep /\w/, glob join '', map { /\w/ ? "{$_,.}" : $_ } split //, shif
+t;
}