g | x | w | all
Bytes Lang Time Link
162Python 3250429T230801ZCrSb0001
080Charcoal191014T210731ZNeil
03805AB1E191007T154951ZGrimmy
137JavaScript ES6191006T215136ZArnauld

Python 3, 164 162 bytes

Same method as @Arnauld.

lambda a:''.join([*map(lambda x:x[4:],sorted(["ANBCODEFPGQSHRIJKLM"[(n:=ord(c)-44032)//588]+"AKBLCMDNERTOFGSUPHIQJ"[n//28%21]+str(~(n%28%18==2))+c for c in a]))])

There was actually a bug in the 164 byte program so that it didn't work for the all-trailing-consonant test case given in the comment section, but I managed to fix that along with finding another 1-byte save. In total, I managed to save 2 bytes.

If output is allowed to be a list of characters, then I can remove the ''.join(...) to get 153 bytes:

lambda a:[*map(lambda x:x[4:],sorted(["ANBCODEFPGQSHRIJKLM"[(n:=ord(c)-44032)//588]+"AKBLCMDNERTOFGSUPHIQJ"[n//28%21]+str(~(n%28%18==2))+c for c in a]))]

Charcoal, 80 bytes

F”&→∧⁶⍘⎚%γD¦ρJG”F”E⎇↓Nη⊙��⭆Ws@}4”F”E↖hY9 t⟧⊙γIO↶5ε∧¬⁶⦃”Φθ⁼℅μΣ⟦⁴⁴⁰³²×⌕βι⁵⁸⁸⍘⁺κλ²⁸

Try it online! Link is to verbose version of code. Explanation: Works by generating all 11172 Hangul syllables in North Korean dictionary order and checking to see which ones are present in the input (so all other characters get deleted; also somewhat slow: takes 18 seconds on TIO). Explanation:

F”&→∧⁶⍘⎚%γD¦ρJG”

Loop over the compressed string acdfghjmopqrsbeiknl. This represents the list of South Korean initial consonants (numbered using the Western lowercase alphabet) in North Korean dictionary order.

F”E⎇↓Nη⊙��⭆Ws@}4”

Loop over the compressed string 02468cdhik1357bgj9eaf. This represents the list of South Korean vowels (numbered using ASCII digits and lowercase alphabet) in North Korean dictionary order.

F”E↖hY9 t⟧⊙γIO↶5ε∧¬⁶⦃”

Loop over the compressed string 013456789abcdefghijlmnopqr2k. This represents the list of South Korean final consonants (using the same numbering as the vowels) in North Korean dictionary order.

Φθ⁼℅μΣ⟦⁴⁴⁰³²×⌕βι⁵⁸⁸⍘⁺κλ²⁸

Concatenate the vowel and final consonant and decode as a base 28 number, then add on 588 times the initial vowel and 0xAC00. Print all characters from the input that have that as their ordinal.

05AB1E, 47 45 38 bytes

Σ•¡®šúIтÝ„Š’#„λ†x!·“•4B33¡€.ā`ââyÇ68+è

Try it online!

Σ                        # sort characters of the input by:
 •...•                   #  compressed integer 13096252834522000035292405913882127943177557
      4B                 #  converted to base 4: 211211121231211111033010101010231002310010331121111111111111111121111111
        33¡              #  split on 33: [2112111212312111110, 010101010231002310010, 1121111111111111111121111111]
           €.ā           #  enumerate each (pairs each digit with its index)
              `ââ        #  reduce by cartesian product (yields a list with 11172 elements)
                 yÇ      #  codepoint of the current character
                   68+   #  + 68
                      è  #  index into the large list (with wraparound)

JavaScript (ES6),  150 148  137 bytes

Saved 10 bytes thanks to @Grimy

I/O: arrays of characters.

a=>a.map(c=>"ANBCODEFPGQSHRIJKLM"[(n=c.charCodeAt()-44032)/588|0]+"AKBLCMDNERTOFGSUPHIQJ"[n/28%21|0]+~(n%28%18==2)+c).sort().map(s=>s[4])

Try it online!

Splitting Hangul syllables

Given a Hangul character of code point 0xAC00 + \$n\$, the initial consonant \$I\$, vowel \$V\$ and final consonant \$F\$ are given by:

$$I=\left\lfloor\frac{n}{588}\right\rfloor,\ V=\left\lfloor\frac{n}{28}\right\rfloor\bmod 21,\ F=n\bmod 28$$

Commented

a => a.map(c =>                  // for each character c in the input:
  "ANBCODEFPGQSHRIJKLM"[         //   start with a letter from 'A' to 'S'
    (n = c.charCodeAt() - 44032) //   for the initial consonant
    / 588 | 0                    //
  ] +                            //
  "AKBLCMDNERTOFGSUPHIQJ"[       //   append a letter from 'A' to 'U'
    n / 28 % 21 | 0              //   for the vowel
  ] +                            //
  ~(                             //   append "-2" for ㄲ or ㅆ (the only North
    n % 28 % 18 == 2             //   Korean final consonants that are sorted
  ) +                            //   differently) or "-1" otherwise
  c                              //   append the original character
)                                // end of map()
.sort()                          // sort in lexicographical order
.map(s => s[4])                  // isolate the original characters