[Question]
  [
Challenge Description:
An anagram is a word or phrase formed by rearranging the letters of another word or phrase. For example, "listen" and "silent" are anagrams. In this challenge, your task is to write a program or function that takes a list of strings as input and returns the unique anagrams.
Write a program or function that takes a list of strings as input and returns the unique anagrams, preserving the order of appearance. Your solution should handle lowercase letters (a-z) only.
Examples:
| Input | Output |
| --- | --- |
| `["cat", "act", "tac", "dog", "god"]` | `["cat", "dog"]` |
| `["a", "ab", "abc", "abcd"]` | `["a", "ab", "abc", "abcd"]` |
| `["cat", "dog", "tac", "god", "act"]` | `["cat", "dog"]` |
The input list contains five strings. The strings "cat", "act", and "tac" are anagrams of each other, and "dog" and "god" are anagrams of each other. The output should contain only one representative from each group of anagrams, preserving the order of appearance. Hence, the output is `["cat", "dog"]`.
Requirements:
The input list can contain duplicate strings, and they should be considered as separate entities.
The output should contain only one representative from each group of anagrams, preserving the order of appearance.
The input list may contain an arbitrary number of strings.
The input list and the output list can be empty.
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest solution in bytes is the winner.
Good luck!
  
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 4 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
Ṣ€Ḣƙ
```
A monadic Link that accepts a list of lists and yields a list of lists containing the first of each anagram.
**[Try it online!](https://tio.run/##y0rNyan8///hzkWPmtY83LHo2Mz/h9sj//@PVkpOLFHSUVBKyU8HUSWJySCquCSxCEQXJZYUg@hkKJ2enwKiEpNLlGIB "Jelly – Try It Online")**
### How?
```
Ṣ€Ḣƙ - Link: list of lists, Words
Ṣ€   - sort each word
   ƙ - group Words by sorted_words and apply to each:
  Ḣ  -   head
```
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal), 32 [bitsv1](https://github.com/Vyxal/Vyncode/blob/main/README.md), 4 bytes
```
⁽sġvh
```
[Try it Online!](https://vyxal.pythonanywhere.com/?v=1#WyJBPSIsIiIsIuKBvXPEoXZoIiwiIiwiW1wiY2F0XCIsIFwiYWN0XCIsIFwidGFjXCIsIFwiZG9nXCIsIFwiZ29kXCJdXG5bXCJhXCIsIFwiYWJcIiwgXCJhYmNcIiwgXCJhYmNkXCJdXG5bXCJjYXRcIiwgXCJkb2dcIiwgXCJ0YWNcIiwgXCJnb2RcIiwgXCJhY3RcIl0iXQ==)
Works well.
## Explained
```
⁽sġvh
⁽sġ   # Group by sorting each word - groups based on first appearance of each word 
  vh  # Get the first word in each group 
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), 28 bytes
```
->l{l.uniq{|z|z.chars.sort}}
```
[Try it online!](https://tio.run/##KypNqvyfZvtf1y6nOkevNC@zsLqmqqZKLzkjsahYrzi/qKS29n@BQlp0tFJyYomSjoJSYjKYKklMBlEp@ekgKj0/RSk29j8A "Ruby – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 6 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
.¡{}€н
```
[Try it online](https://tio.run/##yy9OTMpM/f9f79DC6tpHTWsu7P3/P1opObFESUdBKTEZTJUkJoOolPx0EJWen6IUCwA) or [verify all test cases](https://tio.run/##yy9OTMpM/V9Waa@k8KhtkoKSfeV/vUMLq2sfNa25sPe/zv/oaKXkxBIlHQWlxGQwVZKYDKJS8tNBVHp@ilKsjkK0UiJYSRKETIZSUDmoAVAtUANAOqGmxsYCAA).
Or alternatively:
```
€{DÙkè
```
[Try it online](https://tio.run/##yy9OTMpM/f//UdOaapfDM7MPr/j/P1opObFESUdBKTEZTJUkJoOolPx0EJWen6IUCwA) or [verify all test cases](https://tio.run/##yy9OTMpM/V9Waa@k8KhtkoKSfaXL/0dNa6pdDs/MPrziv87/6Gil5MQSJR0FpcRkMFWSmAyiUvLTQVR6fopSrI5CtFIiWEkShEyGUlA5qAFQLVADQDqhpsbGAgA).
**Explanation:**
```
        #  EXAMPLE INPUT: ["cat","tac","dog","god","act"]
.¡ }    # Group the words in the (implicit) input-list by:
  {     #  Sort the characters of the word
        #   STACK: [["cat","tac","act"],["dog","god"]]
    €   # Then map over each group of words:
     н  #  And only leave the first one
        #   STACK: ["cat","dog"]
        # (after which the list of remaining words is output implicitly)
€       # Map over each word of the (implicit) input-list:
 {      #  Sort the characters of the word
        #   STACK: ["act","act","dgo","dgo","act"]
  D     # Duplicate this list of individually sorted words
        #  STACK: ["act","act","dgo","dgo","act"],["act","act","dgo","dgo","act"]
   Ù    # Uniquify the copy list of strings
        #  STACK: ["act","act","dgo","dgo","act"],["act","dgo"]
    k   # Pop both, and get the indices of the remaining strings
        #  STACK: [0,2]
     è  # Use those indices to index into the (implicit) input-list of words
        #  STACK: ["cat","dog"]
        # (after which the list of remaining words is output implicitly)
```
[Answer]
# [APL (Dyalog Extended)](https://github.com/abrudz/dyalog-apl-extended), 7 bytes
Anonymous tacit prefix function.
```
⊣/∧¨⊢⌸⊢
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT9dNrShJzUtJTfn//1HXYv1HHcsPrXjUtehRzw4g@T/tUduER31TvYL9/R51zNB41Nv3qKv5Ue@aR71bDq03ftQ2ESgZHOQMJEM8PIM1gWqgqv@nqUcrJSeWKOkoKCUmg6mSxGQQlZKfDqLS81OUYtW5QMoSwYqSIGQylILLQg2BaoMaAtINNTlWHQA "APL (Dyalog Extended) – Try It Online")
`⊣/` the first elements of
`∧¨` the each-sorted
`⊢⌸` grouping of
`⊢` the argument
[Answer]
# [Nibbles](http://golfscript.com/nibbles/index.html), 4.5 bytes (9 nibbles)
```
.=~$~`<$/
```
```
.=~$~`<$/
 =~         # group
   $        # the input
    ~       # without sorting the groups
     `<$    # by the results of sorting each element
.           # then map over this list of lists
        /   # folding over each list
            # (implicitly) returning the left-hand argument
            # (so returning the first element of each)
```
[![enter image description here](https://i.stack.imgur.com/D9ewd.png)](https://i.stack.imgur.com/D9ewd.png)
[Answer]
# JavaScript (ES6), 43 bytes
```
a=>a.filter(s=>a[q=[...s].sort()]?0:a[q]=1)
```
[Try it online!](https://tio.run/##HchLCsMwDADRqxSvbGhEsw04OYjxQsgfUkyUWqLXd5Ou3jBv/KJQ30@dDk55FD/Qrwhlb5q7lavDxwcAkAjCXa2L22u5ZvSzG8SHcMvQuNpigyFU83wYpD@KdJO43lROJjo3fg "JavaScript (Node.js) – Try It Online")
### Alternate versions (same size)
```
a=>a.filter(([...s])=>a[s.sort()]?0:a[s]=1)
```
[Try it online!](https://tio.run/##HchLCsMwDADRqxSvJGhFsw24PYjxQvhHiomKJXp9J@nqMfPhH2sa29ceu@Qyq5/sX0x161YGQCAijXiuoKQyDDC@n@tZ0S84k@wqvVCXBhWCS2zufnOc/hiniyztokl2EXEe "JavaScript (Node.js) – Try It Online")
```
a=>a.filter(([...s])=>a[s.sort()]^(a[s]=1))
```
[Try it online!](https://tio.run/##HctbCsMwDETRrRR/yZAKugBnI8YFIT9IMVGxRLfvOvk63IH50I@Ux/G15ym5zBomhZ2wHt3KAIiIqMmvKSqqDAOf3rAihZf3k@VU6QW7NKgQHZO57eGIb4z4Iku7aJJdWp8/ "JavaScript (Node.js) – Try It Online")
### Commented
```
a =>          // a[] = input array
a.filter(s => // for each string s in a[]:
  a[          //   test a[q]:
    q =       //     where q[] is the array
      [...s]  //     made of the characters of s
      .sort() //     sorted in lexicographical order
  ] ?         //   if a[q] is already defined:
    0         //     discard this entry
  :           //   else:
    a[q] = 1  //     set a[q] and keep this entry
)             // end of filter()
```
[Answer]
# [Perl 5](https://www.perl.org/) `-nlF`, 23 bytes
```
$k{"@{[sort@F]}"}||=say
```
[Try it online!](https://tio.run/##K0gtyjH9/18lu1rJoTq6OL@oxMEttlaptqbGtjix8v//5MQSrpT8dK6SxGSu9PwUrsTkkn/5BSWZ@XnF/3V9TfUMDA3@6@bluAEA "Perl 5 – Try It Online")
Input and output are one word per line.
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 5 bytes
```
hM.gS
```
[Try it online!](https://tio.run/##K6gsyfj/P8NXLz34//9opeTEEiUdBaXEZDBVkpgMolLy00FUen6KUiwA "Pyth – Try It Online")
### Explanation
```
hM.gSkQ    # implicitly add k and Q
           # implicitly assign Q = eval(input())
  .g  Q    # group Q by lambda k
    Sk     #   sort k
hM         # take the first element of each group
```
[Answer]
# [Husk](https://github.com/barbuz/Husk), 2 bytes
```
üO
```
[Try it online!](https://tio.run/##yygtzv7///Ae/////0crJSeWKOkoJSaDyJLEZCCZkp8OJNPzU5RiAQ "Husk – Try It Online")
A not particularly clever solution, but seeing that Husk could solve this with half the bytes of other golfing languages I had to post it.
### Explanation
```
üO
ü     Remove duplicates from the list, keyed on
 O       the sorted strings
```
Basically `ü` does exactly what we need for this challenge: for each value in the input list, discard it if it is the same as any previous value when a function is applied to it. The function we use for this comparison is here simply the sorting function.
[Answer]
# [Scala](https://www.scala-lang.org/), 80 bytes
Golfed version. [Try it online!](https://tio.run/##XY7NasMwEITvforFJ4mWkFydypB7ezI5hR62@kNFkVvtkqQYP7srpbiUnj5mdnZ2SWPEZXx7t5rhBUOCqQEw1sG5CIHZUweHnPHrNHAOyb/KDo4pMKh7EuCCEWKgajwXiFYjt4/Qor6DUVeY0Vf40bTyd82UfEiaDwl9xjOVCidq10/ko9zjmMT/WJ3OTVMbXDfYz/Uz1f8RoJar6qcLZiA1WF59IffXjQuRbRY31QcnSNw2NGa2RkrY9juwkSxM9KBWf7992s1yXublGw)
```
w=>{var s=Set[String]();w.filter(x=>if(s(x.sorted)) 0>1 else {s+=x.sorted;0<1})}
```
Ungolfed version. [Try it online!](https://tio.run/##XVBBbsMgELz7FSufsJr6AZEcKT03p6jqocphC2uLCkO00FRV5Le7gElqhQPLzM4sA16iwXl2n18kAxxQW7hWAIp6GCMQyIPfwp4Zfz@OgbUdTs0W3qwO0GUlwAUNGO0T8RqLqCWGegM1ylwCylSUG1IZnKqbu01FvbYy7C0OjKOPI5hGd6EbIdLgRX@OlwdjxaMndaeqZH5w/zhWMX6KtUq/hqtXMHgiG4kDnkt7Ay/OGUJ7EkuIPLDttQnEcM0Qul1uLS/yjgOp98zndrswRaJ7EOmWVjob4v968W9oGujReCpSiseSLa2c7amDlQGedxD4m5q7KKECpuq2T9VUzfMf)
```
object Main {
  def main(args: Array[String]): Unit = {
    val list = List("cat", "act", "tac", "dog", "god")
    val distinctAnagrams = removeAnagrams(list)
    println(distinctAnagrams)
  }
  def removeAnagrams(words: List[String]): List[String] = {
    var seen = Map[String, Boolean]()
    words.filter { word =>
      val sortedWord = word.sorted
      if (seen.contains(sortedWord)) false
      else {
        seen += (sortedWord -> true)
        true
      }
    }
  }
}
```
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), ~~38~~ 33 bytes
```
#&@@@#~GatherBy~Sort@*Characters&
```
Thanks to @att!  
[Try it online!](https://tio.run/##y00syUjNTSzJTE78n2b7X1nNwcFBuc4dJFrkVFkXnF9U4qDlnJFYlJhcklpUrPY/oCgzr8QhzaFaKTmxRElHQQkoAaJKEpNBVEp@OohKz09Rqv0PAA "Wolfram Language (Mathematica) – Try It Online")
[Answer]
# [R](https://www.r-project.org), 70 bytes
```
\(x)x[match(unique(y<-sapply(x,\(s)intToUtf8(sort(utf8ToInt(s))))),y)]
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m72waMGiNNulpSVpuhY33WI0KjQronMTS5IzNErzMgtLUzUqbXSLEwsKcio1KnRiNIo1M_NKQvJDS9IsNIrzi0o0gBotQvI980qAUiCgU6kZCzXtU5pGsoZScmKJko6CUmIymCpJTAZRKfnpICo9P0VJU1OZMxqmCiQeywXWlwjWlQQhk6EURDkQROOSh-pGMg9hK8g6qFNw2QoVAVJQFgGtCIVgQyA-X7AAQgMA)
String manipulation isn't something R is good at.
[Answer]
# [Japt](https://github.com/ETHproductions/japt), 9 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
Could be [4](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&flags=LWc&code=/PEg1Q&input=WyJkb2ciLCAiY2F0IiwgImFjdCIsICJ0YWMiLCAiZG9nIiwgImdvZCJdCi1R) if Japt had a built-in for grouping *without* sorting.
```
üñ mÎñ@bX
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=/PEgbc7xQGJY&input=WyJkb2ciLCAiY2F0IiwgImFjdCIsICJ0YWMiLCAiZG9nIiwgImdvZCJdCi1R)
```
üñ mÎñ@bX     :Implicit input of array U
ü             :Group & sort by
 ñ            :  Sorting
   m          :Map
    Î         :  First element
     ñ        :Sort by
      @       :Passing each X through the following function
       bX     :  First index of X in U
```
[Answer]
# [C# (Visual C# Compiler)](http://www.mono-project.com/docs/about-mono/releases/5.0.0/#csc), 116 bytes
```
a=>a.Aggregate(new Dictionary<string,string>(),(d,i)=>{d.TryAdd(string.Concat(i.OrderBy(m=>m)),i);return d;}).Values
```
[Try it online!](https://tio.run/##VZHdSsQwEIWvN08x7FUCtS9QW1h/ERQFRS/EizGZjYE20Um6UpY@e22XqOzVkDPfDGdOdDzRUU99dN7C4xATdeWt81@VOJLOQ9uSTi74WF6TJ3a6EkK3GCM8cLCMHezFKiZMTsMuOAN36LyMiectr2@AbKOakYXJkvOffYIaPH3Dn7hfa0zrAtYm2KUk1EuxwSwF9aGXkfzKSB5YyLESKyGy9ave69Pf/QXcXPq@I8b3lrLaNLCFesK6wXJjLZPFRHJxdeEOJyMPGS3yhFSFNIVTdbM35RMPG2PyqXNSfrYnXXnPhvhskF3ddErNcMWUevZgqlGVz9j2FKdKbAMT6g@QO2QIcyiwlYdklPoP38fQUvnCLtH8OSSDqsQoxukH "C# (Visual C# Compiler) – Try It Online")
[Answer]
# [Python 3](https://python.org), 91 bytes
```
def h(l):s=set();return[w for w in l if(x:=''.join(sorted(w)))not in s and (s.add(x) or 1)]
```
[Attempt This Online](https://ato.pxeger.com/run?1=dVBLTsMwEN1zisGb2FKoxA4F-SRRZBl_UqPWruIpCSo9CZts4CRcorchjhPKAmbhJ828z4zfPw-vuA1-vHyhiSiUjCYCh_oGpqI1URJJCUSqGVCqBDq0CdqgSVPCDym1G1auUjkLn_KrFlgU_82u6l-e1-CUuGzzV3DzcUR793CptbGwpTtWRR4NUvbYGTx2vu7Bhg56cB524CwdKl4Um-fgPI2hQ6NpzxjzARMjgvQaaNxIrenAYFLeszXizVkQwsu9EQI4h0KIvXReiKKaL0g5rXsxvgQzHIyaHa9fnEmpZIymw2nbmc2SVxaUYMlpbZ_hlsMpD84k7zCOGb8B)
I wonder whether the filter expression can be shortened further.
[Answer]
# [Haskell](https://www.haskell.org/), 64 bytes
```
import Data.List
s=sort
a=map head.groupBy((.s).(==).s).sortOn s
```
[Try it online!](https://tio.run/##FcoxCoQwEEbh3lMMYhGb3GCaZcsFz/BjJIY1mZAZEU@fXasHH2@Hfrfj6D3lKs3oDYP/JLVBWf8wgDMq7RuCj03O@rqd8zp7xzw/faalkPaMVLi2VGzCdEkLOq4wChIpSiCsNvYf "Haskell – Try It Online")
[Answer]
# [Julia 1.0](http://julialang.org/), 17 bytes
```
!x=unique(sort,x)
```
[Try it online!](https://tio.run/##dY1BCsIwEEXX9hTjrFIIAQ9Q8QKeQLsY21FGQlKTVHr72rRFEXEW8@H/P/PuvRXaDeO4HareyaNnFX1IeijHqw8gIA4CU2vFcVRlAdOQZqiAn2SNOnIi01GIbFTsrCQlGs8Jy3Lphql59@KM2s6xUaQR17AL4pJ1iqDaQ1i8A8XIIeXDiVGwa8cTNpRQA1IzS6ImS@tvWW6@xRo271K26@KENF9clt2sslb/ZcXXlw8qM1b@D@oF "Julia 1.0 – Try It Online")
input and output are a list of lists of characters
28 bytes with a list of strings as input and output: [Try it online!](https://tio.run/##dY1RDoIwDIaf5RRlT1uCSzwAxgt4AuShskpqloHbMNweGRCNMfahf9N@/f/7YBkP4zTlYzk4fgwkeX8MnY@yYq11rYpRTbfOAwM78ITGsqMgVQZzYUFQAj3RanmmiLpHH0jL0FuOkgtxiUKplfUzmeMy9p5dtE4ilEfw6/mEIZCPCZsdM3JmqkSDURQgsFkkYpPEdG2StjOiht0bSus6qwQuH9e1N5ts6L9b9uXyiUoZW/5P1As "Julia 1.0 – Try It Online")
[Answer]
# C (gcc), 277 bytes
```
#define C(A,L)for(int i=A=0;L[i];L[i++]==t&&++A);
i,j,k,x,y,r,t;D(char*a,char*b){for(r=k=0;(t=a[k])||b[k];++k){if(!a[k]||!b[k]){++r;break;}C(x,a)C(y,b)x-y!=0&&++r;}}
main(int c,char**v){for(i=1;i<c;++i){for(j=i-1;j>0;--j){D(v[j],v[i]);if(r==0)goto B;}printf("%s ",v[i]);
B:1;}}
```
[Try it online!](https://tio.run/##LY/NboMwEITveQpI1cgbGwmu2boSIce8AeJgzE8NLVSORUHAq9c1pJcdabQ736wMaimtfSnKSnWll5CY3aHqNVGd8RSPeYj3VGXboDTj3JxOlMaAB8Ua1rKRTUwzgzciP4Q@C7ZLDvMWoXnrzonhIm0zWJbcCVLawqwq4m/msvibCTOlGnNdihbXhIxMQEImlsMYTD4PN6TGdf0Sqtt7ySfmPIC3gxSPUL1Jl62e5IarIMLmPcQgaGC@kSFtMja4RwAdW3MeQt2b3rvi@q1dZEWOrw/v@L9yuF4ix7PWSmFs0dfWCGnrvrBCml9ZfYr6YYOfPw)
Readable version:
```
#define C(A,L)for(int i=A=0;L[i];L[i++]==t&&++A);
i,j,k,x,y,r,t;
D(char*a,char*b){
    for(r=k=0;(t=a[k])||b[k];++k){
        if(!a[k]||!b[k]){++r;break;}
        C(x,a)
        C(y,b)
        x-y!=0&&++r;
    }
}
main(int c,char**v) {
    for(i=1;i<c;++i){
        for(j=i-1;j>0;--j){
            D(v[j],v[i]);
            if(r==0)goto B;
        }
        printf("%s ",v[i]);
B:1;
    }
}
```
Explanation:
Not the most efficient approach but light on code: go through each item in the list (given as arguments), compare to each prior item using a difference function D, and print if none of them matched.
To check matching, the difference function goes through each character in the first string and counts the number of occurrences in either string of that character. If at any point either that number differs or we have finished processing one string while the other is still going, we consider the two non-matching.
To save bytes, I added the counting macro C, which accumulates into variable A the number of occurrences of global character t in list L.
-
# C (gcc), 303 bytes (alternate answer)
```
typedef unsigned long long u;n,i,j,k,z;u t;u y(n){return n==1?1:z*y(n-1)+1;}s(char* v){for(k=t=0;v[k];++k)t+=y(v[k]-96);}main(int c,char *v[]){long f[c];for(i=1;i<c;++i)for(j=0;v[i][j];++j>z&&++z);for(i=1;i<c;++i){s(v[i]);for(j=n,k=0;j>0;--j){f[j-1]==t&&++k;}if(k)continue;printf("%s ",v[i]);f[n++]=t;}}
```
[Try it online!](https://tio.run/##ZY5BbsMgEEWvgiI1ggBS2FRqKelBkBcI2xRIxpGNXdmWr15qku66mJFm5v8333Jnbc5pvjd106IRBu@gqdG1A/dsowTmWWCRLXJEaa8ZA1n7Jo09IFBKfIr35bQvuSBUyG3A9sv0JzSRte16HFVSZznpWElKI0lUzbhM/O2VyO1mPGAPCVlWXOg06Yqsj8ettpUsBK@E9B92t3tS5vDg@UqHggyX5XikdCH/tOuAi@x5CApY3I3hcpachz2bDlxUSqXijnLzLY7EdpA8jI2893uoFh9eBnRgfxQNlFYqyW3LOVuTct25nIzNrquzsenHtlfjhsy/fwE "C (gcc) – Try It Online")
Readable version:
```
typedef unsigned long long u;
n,i,j,k,z;u t;
u y(n){return n==1?1:z*y(n-1)+1;}
s(char* v){for(k=t=0;v[k];++k)t+=y(v[k]-96);}
main(int c,char *v[]) {
    long f[c];
    for(i=1;i<c;++i)for(j=0;v[i][j];++j>z&&++z);
    for(i=1;i<c;++i){
        s(v[i]);
        for(j=n,k=0;j>0;--j){f[j-1]==t&&++k;}
        if(k)continue;
        printf("%s ",v[i]);
        f[n++]=t;
    }
}
```
Explanation:
For sufficiently short strings, this alternate approach will work. We are calculating a signature, which is something like a checksum but reserving non-overlapping number ranges for the potential counts of each letter, for each given list item. We go through the items and then, each time we encounter a novel signature, we print the item and store the signature.
These signatures as currently calculated get *really* large *really* fast, so this will only work for short words. Realizing this, I switched to the other approach, but still thought it was interesting enough to include.
I suspect that with a little more work, this could not only work for arbitrarily-long arguments, but also do so with a lighter footprint than the first approach!
[Answer]
# [Arturo](https://arturo-lang.io), 32 bytes
```
$=>[gather&=>sort|map[k,v]->v\0]
```
[Try it!](http://arturo-lang.io/playground?QZ0kU8)
Collect input strings in a dictionary where the key is the sorted string and the value is a list of strings that sort to that key, then map each dictionary entry to its first value. Input is taken as a list of lists of code points.
[Answer]
# Excel, 99 bytes
```
=LET(r,ROW(A:A),b,BYROW(A:A,LAMBDA(s,CONCAT(SORT(MID(s,r,1))))),FILTER(A:A,(b<>"")*MATCH(b,b,0)=r))
```
Note: This takes quite a long time to run on my weak machine and sometimes just locked Excel. For the sake of the screenshots below, I changed the range references from `A:A` to just `A1:A10`. The logic is all the same, though.
Input is one string per cell in column A.
* `LET(r,ROW(A:A)` creates an array of values 1 to 1,048,576 and assigns it to the variable `r`.
* `b,BYROW(A:A,LAMBDA(s,CONCAT(SORT(MID(s,r,1)))))` takes each string, splits it into pieces, sorts those pieces, and then combines them back into a string. The array of all these new, sorted strings is assigned to the variable `b`.
* `FILTER(A:A,(b<>"")*MATCH(b,b,0)=r)` filters out the values where that result array `b` is blank and then only returns the strings from the input array where their index in the input matches the first instance of their sorted string in the sorted string array `b`.
[![Screenshot](https://i.stack.imgur.com/nIjgM.png)](https://i.stack.imgur.com/nIjgM.png)
There are probably shorter ways to do this and I welcome someone pointing them out.
[Answer]
# [PowerShell Core](https://github.com/PowerShell/PowerShell), 53 bytes
```
$args|?{($k="$($_|% t*y|sort)")-notin$s-and($s+=,$k)}
```
[Try it online!](https://tio.run/##dY7dToMwFMfveYqTprpW6SMQMWbeauTCC2OWrnSMDelsS6YBnh1XvsYW7EVPcs7/43dQR6nNVmYZE0rLBm@CssFcJ6Z6KAneBwgTvKpuwN79VkZpSxFlubJpjg3jeUywuQ98vKd1U3teSDw4PR9CEhIkuEU@IC7aYblwI1aJG4mKEXW6QeX2lE7tvDWvu1/0Y3D9d6QzAH1lD@Cae6o5AAoVPCu95GLLXtY7KSyUbSY@Kh0bH7D8OZy2MoYA8Ko7aWmKzJ4Wt3gDYSvsDoP20URWp3niPKOf7VSaw8JfTEOmyj72UvfxGj0Vxqqvju4z7PDciwohpDHTkjGOye/ritH37oDB2Vr0q0L3lgPzXPaoeut4z@gXitqrveYP "PowerShell Core – Try It Online")
Takes the words arguments using splatting, returns a list or words.
It works by building a list of keys for each word by sorting its letters alphabetically:  
e.g. `cat` has the key `a c t`  
Then for each word `$_`, if the word's key `$k` is not in the list `$s`, add `$k` to `$s` and return `$_`
[Answer]
# [Factor](https://factorcode.org/) + `sets.extras`, 22 bytes
```
[ [ sort ] unique-by ]
```
Factor has the perfect combinator for this, `unique-by`, which returns a list of the first unique values in a list after a function has been applied to each element. Requires Factor build ~2207+ for `sort`, hence this won't work on TIO or ATO.
[![enter image description here](https://i.stack.imgur.com/PfqF2.png)](https://i.stack.imgur.com/PfqF2.png)
[Answer]
# [simply](https://github.com/ismael-miguel/simply), ~~105~~ 100 bytes
Yes, it's very long, but makes use of the built-in `&marsagain`.  
(It's an anagram for `&is_anagram`, that happens to be 1 byte shorter.)
```
fn($x){$A=[]each$X in$x{$L=0each$a in$A if!$L$L=&marsagain($X$a)if!$L$A=&array_concat($A$X)}send$A;}
```
Defines an anonymous function that takes an array of strings and returns an array of strings.
---
---
## Ungolfed
This is the same code, but ungolfed.
### Code-like
```
anonymous function($words) {
    $anagrams = [];
    each $word in $words {
        $in_the_list = false;
        each $anagram in $anagrams {
            unless $in_the_list then {
                $in_the_list = &is_anagram($word, $anagram);
            }
        }
        
        unless $in_the_list then {
            $anagrams = &array_concat($anagrams, $word);
        }
    }
    
    return $anagrams;
};
```
### English-like
```
Set the variable $fn to an anonymous function with arguments($words)
Begin.
    Set the variable $anagrams = [].
    Foreach $word in $words
    Begin.
        Set the variable $in_the_list to false.
        
        Foreach $anagram in $anagrams
        Begin.
            Unless $in_the_list then
            Begin.
                Set the variable $in_the_list to the result of calling the function &is_anagram with the arguments ($word, $anagram).
            End.
        End.
        
        Unless $in_the_list then
        Begin.
            Set the variable $anagrams to the result of calling the function &array_concat with the arguments ($anagrams, $word).
        End.
    End.
    
    Return the value of $anagrams.
End.
```
Both variants do the same.
---
---
## Testing it
To test it, you have to assign it to a variable, E.g.:
```
$fn = fn($x){$A=[$x->0]each$X in$x{$L=0each$a in$A if!$L$L=&marsagain($X$a)if!$L$A=&array_concat($A$X)}send$A;};
// Copy-paste from the tests
$result = call $fn(["cat", "dog", "tac", "god", "act"]);
// Should output ["cat","dog"]
echo &json_encode($result);
```
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 20 bytes
```
ＷＳＦ⬤υ⊙⁺ικ⁻№ιμ№κμ⊞υιυ
```
[Try it online!](https://tio.run/##JYxBCgMhDEX3OUWWEewJZjV01UVB6AnEaVUm1eIkLT29Vfp378H7IfkWqufePynzHelSXio3ablEMgYftSGtzKQW1/Ilx3pQtrgbi9dcBpyrFpnqOdQf9glz6PRIM81mATc@hdQsvQcv4IOA@ABbjRDrBv305h8 "Charcoal – Try It Online") Link is to verbose version of code. Takes input as a list of newline-terminated strings. Explanation:
```
ＷＳ
```
Repeat for each input string.
```
Ｆ⬤υ⊙⁺ικ⁻№ιμ№κμ
```
If none of the unique anagrams so far are anagrams of this string, then...
```
⊞υι
```
... add this string to the list of unique anagrams so far.
```
υ
```
Output the final list of unique anagrams.
[Answer]
# [Thunno 2](https://github.com/Thunno/Thunno2), 4 [bytes](https://github.com/Thunno/Thunno2/blob/main/docs/codepage.md)
```
ñṠ€h
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m728JKM0Ly_faMGCpaUlaboWKw9vfLhzwaOmNRlLipOSi6GiC24qRyslJ5Yo6SgoJSaDqZLEZBCVkp8OotLzU5RiIWoB)
#### Explanation
```
ñṠ€h  # Implicit input
ñṠ    # Group by sorting
  €h  # First item of each
      # Implicit output
```
]