In short:
Control sequences are all tokens starting with the escapechar (usually \). There is one exception: Control sequence tokens which have been let to a non-active character token (like \bgroup) are not control sequences in the sense of \token_if_cs:N(TF).
Macros are all control sequences or active characters defined with \def and friends.
Examples (in the sense of the conditionals of the question):
\newcommand or \documentclass are both control sequences and macros,
\def, \relax, or \dimen@ are control sequences but not macros, and
~ is a macro but not a control sequence
\bgroup is neither a macro nor a control sequence.
(assuming standard definitions). Undefined control sequences like \@undefined are no macros and active characters with no definition are neither macros nor control sequences.
A look at the definitions:
If we look at the definition of both conditionals we find:
\token_if_cs:N(TF):
\prg_new_conditional:Npnn \token_if_cs:N #1 { p , T , F , TF }
{
\if_catcode:w \exp_not:N #1 \scan_stop:
\prg_return_true: \else: \prg_return_false: \fi:
}
This means every token which has the same category code as \scan_stop: (\relax) as \if_catcode:w (\ifcat) sees it. Citing TeX by Topic that is the “special category code 16”.
TeX expands whatever is after \ifcat until two unexpandable tokens are found; these are then compared with respect to their category codes. Control sequence tokens are considered to have category code 16, which makes them all equal to each other, and unequal to all character tokens.
\token_if_macro:N(TF):
\use:x
{
\prg_new_conditional:Npnn \exp_not:N \token_if_macro:N ##1
{ p , T , F , TF }
{
\exp_not:N \exp_after:wN \exp_not:N \__token_if_macro_p:w
\exp_not:N \token_to_meaning:N ##1 \tl_to_str:n { ma : }
\exp_not:N \q_stop
}
\cs_new:Npn \exp_not:N \__token_if_macro_p:w
##1 \tl_to_str:n { ma } ##2 \c_colon_str ##3 \exp_not:N \q_stop
}
{
\if_int_compare:w \__str_if_eq_x:nn { #2 } { cro } = \c_zero
\prg_return_true:
\else:
\prg_return_false:
\fi:
}
This checks if \meaning<token> contains the string macro: (all category code 12 characters) which is true if the token has been defined with \def and friends.
A small test file:
Remark: the test macro \tokentest below not actually grabs the first token but is defined with a standard non-delimited argument.
\documentclass[twocolumn]{article}
\usepackage[T1]{fontenc}
\usepackage{xparse}
\newcommand*\cs[1]{\expandafter\texttt\expandafter{\string#1}}
\ExplSyntaxOn
\cs_new_protected:Npn \token_check:N #1
{
\noindent \cs #1 ~ is~
\token_if_macro:NF #1 { \emph {not} ~ }
a~ macro \
\cs #1 ~ is~
\token_if_cs:NF #1 { \emph {not} ~ }
a~ control~ sequence \par
meaning: ~ \expandafter \texttt \expandafter { \meaning #1 } \par
\medskip
}
\NewDocumentCommand \tokencheck {m}
{ \token_check:N #1 }
\ExplSyntaxOff
\def\a{}
\def\b#1{}
\long\def\c{}
\protected\def\d{}
\def\1{}
\begin{document}
\makeatletter
\subsection*{Defined with \cs\def}
\tokencheck\a
\tokencheck\b
\tokencheck\c
\tokencheck\d
\tokencheck\1
\tokencheck~
\subsection*{Undefined}
\tokencheck@undefined
\newpage
\subsection*{Primitives}
\tokencheck\def
\tokencheck\relax
\tokencheck\fi
\tokencheck\ \relax
\subsection*{Defined with \cs\newbox, \cs\chardef, \dots}
\tokencheck&
\tokencheck\strutbox
\tokencheck\dimen@
\tokencheck\skip@
\makeatother
\end{document}

\defand friends, i.e., every token where\meaningsays “macro:”. If that is correct I'm happy to self-answer my question. – cgnieder Feb 14 '17 at 20:32\ifcatuntil two unexpandable tokens are found; these are then compared with respect to their category codes. Control sequence tokens are considered to have category code 16 […]” – cgnieder Feb 14 '17 at 20:37\meaningof macros starts with one of the following phrases:macro:->or\long macro:->or\outer macro:->or\long\outer macro:->. A macro can be either a control sequence token (i.e. a control word token or a control symbol token) or an active character token. But I doubt that there is a test based on processing macro-arguments which is suitable for\outermacros as well. – Ulrich Diez Feb 15 '17 at 08:23\ifcat-comparison with control sequence tokens only applies to such control sequence tokens that are not\letequal to a non-active character token. E.g., with\let\bgroup={the category code of the control sequence token\bgroupwill usually be 1 as the catcode of{usually is 1 also. Preceding\noexpanddoesn't do anything about that as it also wouldn't do anything about that when preceding the{-character-token. – Ulrich Diez Feb 15 '17 at 08:40\bgroupis neither a macro nor a control sequence… – cgnieder Feb 15 '17 at 08:57\bgroupdefinitely is a control word token while control word tokens in turn are control sequence tokens. Besides this I am not quite sure whether\tokencheckis the correct name for a control sequence token that actually does not necessarily work on single tokens but actually does work on macro arguments while macro arguments might consist of several tokens or be empty as well... – Ulrich Diez Feb 15 '17 at 09:13\token_if_macro:N(TF)and\token_if_cs:N(TF). Maybe I should delete it from the answer… – cgnieder Feb 15 '17 at 09:22\stringto the same token several times with the integer parameter\escapecharhaving different values. If the results of "stringifying" differ, then the token in question is a control sequence token. Otherwise it is not. – Ulrich Diez Feb 15 '17 at 09:30