You can iterate over all characters, testing the catcode of every one of them. Then just print the active/mathactive(\mathcode="8000) ones:
\documentclass{article} \begin{document} \newcount\currentchar \currentchar=0 \loop \ifnum\active=\catcode\currentchar Character code \number\currentchar, aka ``\texttt{\char\currentchar}'', is active. It's meaning is:\\ \texttt{% \lccode`\~=\currentchar\lowercase{\meaning~} }.\par \else \ifnum"8000=\mathcode\currentchar Character code \number\currentchar, aka ``\texttt{\char\currentchar}'', is mathactive. It's meaning is:\\ \texttt{% \lccode`\~=\currentchar\lowercase{\meaning~} }.\par \fi \fi \advance \currentchar by 1 \ifnum\currentchar<256 \repeat \end{document}
This also tries to output the character (Of course this only works if there is a printable character in that position) and the definition. You will find that there are lots of active characters, mostly coming from inputenc.
The most interesting part of the output probably is: 
For Unicode engines like XeLaTeX and LuaLaTeX, you have to replace 256 by "110000 (the number of Unicode codepoints) and "8000 by "1000000. So you get
\documentclass{article} \begin{document} \newcount\currentchar \currentchar=0 \loop \ifnum\active=\catcode\currentchar Character code \number\currentchar, aka ``\texttt{\char\currentchar}'', is active. It's meaning is:\\ \texttt{% \lccode`\~=\currentchar\lowercase{\meaning~} }.\par \else \ifnum"1000000=\mathcode\currentchar Character code \number\currentchar, aka ``\texttt{\char\currentchar}'', is mathactive. It's meaning is:\\ \texttt{% \lccode`\~=\currentchar\lowercase{\meaning~} }.\par \fi \fi \advance \currentchar by 1 \ifnum\currentchar<"110000 \repeat \end{document}
Here, inputenc is not needed, so you only get what you expect (This is LuaLaTeX, for XeTeX \mathcode works slightly different): 