Q:

How can I force a throw to be a statement and not an expression (in a lambda expression)?

Starting from C# 7.0 the throw keyword can be used both as an expression and as a statement, which is nice.
Though, consider these overloads
public static void M(Action doIt) { /*use doIt*/ }
public static void M(Func<int> doIt) { /*use doIt*/ }

When invoking like this
M(() => throw new Exception());

or even like this (with a statement lambda)
M(() => { throw new Exception(); });

the M(Func<>) overload is selected by the compiler indicating that the throw is here considered as an expression.
How can I elegantly and intent-clear force the compiler to select the M(Action) overload?
One way to do it is this
M(() => { throw new Exception(); return; });

but the reason for the return statement seems non-obvious, and runs the risk of being changed by the next developer especially since Resharper warns about the unreachable code.
(Of course I can change the method naming to avoid overloading, but that is not the question. :-)

A:

You could add a cast to for Action, although it does get a bit LISP'y with all the parentheses:
M((Action)(() => throw new Exception()));

Not ideal, but if you want maximum clarity:
Action thrw = () => throw new Exception();
M(thrw);

A:

This has nothing to do with whether the lambda is a statement lambda or an expression lambda (as is most succinctly shown by you changing the lambda from an expression lambda to a statement lambda and the behavior not changing).
There are numerous ways you can make a lambda match multiple possible overloads. This one is specific to newer versions, but other methods have applied since C# 1.0 (and the specific handling of anonymous methods and the resulting overload resolution disambiguation has needed to exist since the introduction of anonymous methods).  
The rules for determining which overload is called are spelled out in section 7.5.3.3 of the C# specs.  Specifically, when the parameter is an anonymous method, it will always prefer the overload who's delegate (or expression) has a return value over one that has no return value.  This will be true whether it's a statement lambda or expression lambda; it applies to any form of anonymous function.  
Thus you either need to prevent both overload from matching by making the anonymous method not valid for a Func<int>, or explicitly force the type to be an Action so the compiler is not disambiguating it itself.

A:

One possible approach is to use named parameters:
public static void M(Action action) { /* do stuff */ }

public static void M(Func<int> func) { /* do stuff */ }

public static void Main()
{
    M(action: () => throw new Exception());
}

This should probably be documented in the code so as not to surprise the next developer to come along, and as noted in the comments write an appropriate automated test to verify the correct overload is called.

