I ++ed your reply when I first saw it, but I'm having second thoughts. (But I won't try to take back my upvote. :)
A solution based on uniq (which utilizes a hash under the hood) preserves the order of items in the input list (with only the first of a set of non-unique items being output) whereas the method using sort does not. If information on the particular input list items that were not unique is needed, a single hash can be used both for uniqifying and for counting (and a hash reference is not needed).
Win8 Strawberry 5.8.9.5 (32) Tue 07/26/2022 5:28:42
C:\@Work\Perl\monks
>perl
use strict;
use warnings;
my $s = "#tag2 #tag1 #tag2 #tag3 #tag1";
print qq{Orig: '$s' \n};
my %u;
$s = join ' ', grep { ! $u{$_}++ } split /\s+/, $s;
print qq{Uniq: '$s' \n};
printf qq{Dups: '%s' \n}, join ', ', sort grep { $u{$_} > 1 } keys %u;
^Z
Orig: '#tag2 #tag1 #tag2 #tag3 #tag1'
Uniq: '#tag2 #tag1 #tag3'
Dups: '#tag1, #tag2'
Note: uniq may be found in List::MoreUtils rather than in List::Util in older versions of Perl.
Give a man a fish: <%-{-{-{-<
|