Here's a LuaLaTeX-based solution. It defines a Lua function that does most of the work, plus a couple of LaTeX utility macros that activate and deactivate the Lua function. By "activate", I mean "assign the Lua function to LuaTeX's process_input_buffer
callback", so that it may act as a preprocessor on the input stream before TeX starts its usual processing.

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage[french]{babel} % for "\og" and "\fg" macros
\usepackage[french=guillemets]{csquotes} % for "\enquote" macro
\usepackage{luacode} % for "luacode" environment
%% Lua-side code
\begin{luacode}
function delete_whitespace ( s )
s = s:gsub ( "«[ ~]*" , "\\og " )
s = s:gsub ( "[ ~]*»" , "\\fg " )
-- s = s:gsub ( "[ ~]+([%:%;%?%!])" , "%1" ) -- if needed
return s
end
\end{luacode}
%% LaTeX-side code
\newcommand\DeletewhitespaceOn{\luadirect{luatexbase.add_to_callback (
"process_input_buffer", delete_whitespace , "deletewhitespace" )}}
\newcommand\DeletewhitespaceOff{\luadirect{luatexbase.remove_from_callback (
"process_input_buffer", "deletewhitespace" )}}
\AtBeginDocument{\DeletewhitespaceOn} % enable by default
\begin{document}
\enquote{bla} \og{}bla\fg{} «bla» « bla » «~bla~» «~ bla ~ »
\DeletewhitespaceOff
\enquote{bla} \og{}bla\fg{} «bla» « bla » «~bla~» «~ bla ~ »
\end{document}
\catcode`~=10
would change the category code of the tilda~
into a space which could then be ignored by\ignorespaces
. I am not sure if this would work but worth a try.\relax
, close it on closing guillemet?luatex
tag -- does this mean that using LuaLaTeX is an option for you and your coauthors? Please confirm.