The Challenge:

Print every 2 letter word acceptable in Scrabble using as few bytes as possible. I have created a text file list here. See also below. There are 101 words. No word starts with C or V. Creative, even if nonoptimal, solutions are encouraged.

AA
AB
...
ZA


Rules:

• The outputted words must be separated somehow.
• Case does not matter, but should be consistent.
• Trailing spaces and newlines are allowed. No other characters should be outputted.
• The program should not take any input. External resources (dictionaries) cannot be used.
• No standard loopholes.

Wordlist:

AA AB AD AE AG AH AI AL AM AN AR AS AT AW AX AY
BA BE BI BO BY
DE DO
ED EF EH EL EM EN ER ES ET EX
FA FE
GO
HA HE HI HM HO
ID IF IN IS IT
JO
KA KI
LA LI LO
MA ME MI MM MO MU MY
NA NE NO NU
OD OE OF OH OI OM ON OP OR OS OW OX OY
PA PE PI
QI
RE
SH SI SO
TA TI TO
UH UM UN UP US UT
WE WO
XI XU
YA YE YO
ZA

• Do the words have to be outputted in the same order? – Sp3000 Aug 13 '15 at 3:26
• @Sp3000 I'll say no, if something interesting can be thought up – qwr Aug 13 '15 at 3:29
• Please clarify what exactly counts as separated somehow. Does it have to be whitespace? If so, would non-breaking spaces be allowed? – Dennis Aug 13 '15 at 14:14
• Ok, found a translation – Mikey Mouse Aug 13 '15 at 15:16
• Vi isn't a word? News to me... – jmoreno Aug 15 '15 at 15:23

Python 239 bytes

import re;f=lambdax:''.join(re.findall('..',x));a,b='ABAHALAMANATAYDEDOEFEHEMENERHOISITMOMUNONUOSOWOY','AAADAEAGAIARASAWAXBEBIBOBYELESETEXFAGOHIHMIDIFINJOKAKILILOMIMMMYOEOFOIOPOROXPAPEPIQISHTOUHUPUSUTWEXIXUYEZA';print f(a),f(a[::-1]),f(b)


This is a bit long, but I've given it a try. I've counted all the patterns that also have the reversed counterparts. Ex) 'AB'/'BA' and so on.

Python 3, 248 bytes

e=enumerate
[print(*(chr(x+65)+chr(j+65)+" "for j,i in e(bin(k)[2:])if int(i)))for x,k in e([30292443,16793873,0,16400,9320616,17,16384,20753,794664,16384,257,16641,17846545,1064977,29798840,273,256,16,16768,16641, 831616,0,16400,1048832,16401,1])]


The numbers were generated by an additional script
I'm sure that it can be optimized further

PHP, 170 bytes

shortest approach I could find so far ...

for(;$c=ABFHKLMNPTYZ1A2AEIO1ABDFHMNOPRWY1EIO1A1AEOSU1ABHKJMOPQSTX3AE1AEHMOU1AEIOU1BDGHJLMNSTWY1OU11AEO1AEIOU1AEIU1MNX2AO1AEO1ABMO[$i++];)$c<1?print$c.chr($k+65)._:$k+=$c;  breakdown for(;$c=CHARACTERS[$i++];) // loop$c through map
$c<1 // if$c is a letter (integer value < 1)
?print$c.chr($k+65)._           // print first letter, second letter, delimiter
:$k+=$c                         // else increase second letter
;


Note The shortest bit-mapping version with printable ascii costs 190 bytes (113 bytes data+77 bytes decoding) using 6 bits=base 64, 174 bytes (97 data, 77 decoding) using 7 bits (base 128); possibly some more for escaping.

for(;$p<676;) // loop through combinations ord("MAPPING"[$p/6])-32>>$p%6&1 // test bit ? // if set, do nothing :print chr($p/26+65).chr($p++%26+65)._; // if not, print combination+delimiter  Base 224 (using ascii 32..255) takes 87 bytes data (+ escaping); but I guess the decoding will cost more than 10 bytes extra. Excluding C and V from the map would save 16/14/13 bytes on the data but cost a lot in decoding. Retina, 167 bytes (non-competing)  ¶AABDEGHIcWXY¶BbOY¶DEaEDFHcX¶FAE¶GaHbMaIDFNST¶JaKAI¶LAIaMbMOUY¶NAEOU¶ODEFHIMNPRSWXY¶Pb¶QI¶RE¶SHIaTAIaUHMNPST¶WEaXIU¶YAEaZA c LMNRST b AEI a O¶ +(¶(.)\S+)(\S)$1 $2$3
`

Try it online!