This might be done with pure expansion, but since you're using xstring
it's not really necessary:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\mylist}{ m o }
{
\clist_clear:N \l_tmpa_clist
\clist_map_inline:nn { #1 }
{
\clist_put_right:No \l_tmpa_clist { ##1 }
}
\IfNoValueTF{#2}
{ \l_tmpa_clist }
{ \clist_set_eq:NN #2 \l_tmpa_clist }
}
\ExplSyntaxOff
\newcommand\stringA{A}
\newcommand\stringB{}
\newcommand\stringC{C}
\begin{document}
\mylist{\stringA,\stringB,\stringC}
\mylist{\stringA,\stringB,\stringC}[\listA]
\show\listA
\end{document}
The \show\listA
command produces
> \listA=macro:
->A,C.
Without an optional argument the result will be simply printed.
If you want to print the resulting list with a space following the comma, then a different approach is needed:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\mylist}{ m }
{
\seq_clear:N \l_tmpa_seq
\clist_map_inline:nn { #1 }
{
\tl_if_empty:oF { ##1 } { \seq_put_right:No \l_tmpa_seq { ##1 } }
}
\seq_use:Nn \l_tmpa_seq {,~}
}
\ExplSyntaxOff
\newcommand\stringA{A}
\newcommand\stringB{}
\newcommand\stringC{C}
\begin{document}
\mylist{\stringA,\stringB,\stringC}
\end{document}
In case you want to avoid that \newcommand{\stringB}{ }
prints a space, use \tl_if_blank:oF
instead of \tl_if_empty:oF
.