xlsclients is close (and a standard part of X), it lists the X server's clients. But, there might not be a 1:1 mapping between what you consider an "application" and what X considers a "client". My single running instance of LyX consumes 13 clients for example, if I use xlsclients -l (long-form output) I can see only one of them has a defined "Icon Name", but this is only a hint. Also, since it uses XQueryTree() it may miss some windows (it doesn't find any xpdf windows I have open).
It also doesn't give very much information, what you can do though is use xlsclients -l to obtain the window id, and query each window with xprop -id $ID. For more details on a window, use xwinifo, though it cares about "windows" which are not the same thing as clients or applications:
xwininfo -root -children
xwininfo -root -tree # indented view
Depending on your window manager, you may be able to inspect certain window properties (e.g. _NET_xxx or _NET_WM_xxxx properties) to determine if something is an "application". If the window manager client or GUI library sets it (any contemporary one should) the _NET_WM_PID property is the simplest (though imperfect) way to associate a PID with a specific window. I don't know of a tool that ties all these pieces together.
I use the window manager FVWM, I can talk directly to it using FvwmCommand, e.g. FvwmCommand -i1 send_windowlist shows me the list of windows. @Arkadiusz' suggestion to use wmctrl seems like a good and window manager agnostic way to do the same thing.
One more trick is to query the root window's _WIN_CLIENT_LIST, via bash:
$ xwininfo -root
xwininfo: Window id: 0x69 (the root window) (has no name)
[..]
$ IFS=",= " read -a win < <(xprop -notype -id 0x69 32x _WIN_CLIENT_LIST )
$ for ((ww=1; ww<${#win[*]}; ww++)); do
printf "%i %s\n" $ww ${win[$ww]};
xprop -id ${win[ww]} -notype _NET_WM_PID WM_NAME WM_CLASS \
WM_ICON_NAME WM_CLIENT_LEADER;
done
This exactly matches what my WM lists as windows (without those I have configured to be excluded from the WM window list). Child windows set WM_CLIENT_LEADER to their parent (for session management), though the parent window may not be visible (firefox does this), and may point to itself.
xrestop gets my vote though.