I've now solved the display issue by making my Perl script change the codepage to 65001 just like CMD's `dir` does:
use feature ":5.16"; # Include say and Unicode string functions.
use open ':std', ':encoding(UTF-8)'; # Print Unicode without complaining about wide chars.
use utf8; # Unicode source code.
use strict; # Don't ignore undefined variables.
use Win32::Console;
Win32::Console::OutputCP(65001); # Tell Windows Terminal to render Unicode (with unclustered graphemes in 1.23.13503.0 but they copy/paste ok).
my $file_name = "emoji_🎅🎉😀💢👩🏾🚀.txt";
say "Writing to ${file_name}";
open( my $fh, ">", $file_name ) or die "Can't write $file_name: $!";
binmode($fh, ":encoding(UTF-8)"); # encoding() also checks UTF-8 validity, unlike ":utf8".
say $fh "My name is \"$file_name\".";
close($fh);
say "Reading ${file_name}";
open( $fh, "<", $file_name ) or die "Can't read $file_name: $!";
binmode($fh, ":encoding(UTF-8)");
read($fh, my $buf, 100);
say $buf;
close($fh);
say "Done.";
This won't affect the codepage of the terminal after, just like `dir`:

And despite the female black astronaut not rendering as a single character, it copy/pastes just fine:
15:23:45 C:\apps\StrawberryPerl\perl\bin>chcp
Active code page: 850
15:23:50 C:\apps\StrawberryPerl\perl\bin>perl C:\Users\C\Documents\code\Perl\test_unicode.pm
Writing to emoji_🎅🎉😀💢👩🏾🚀.txt
Reading emoji_🎅🎉😀💢👩🏾🚀.txt
My name is "emoji_🎅🎉😀💢👩🏾🚀.txt".
Done.
15:23:53 C:\apps\StrawberryPerl\perl\bin>chcp
Active code page: 850