This doesn't look like parameter sniffing.
The CompiledValue and RunTimeValue is the same for all parameters even in the bad.sqlplan
<ParameterList>
<ColumnReference Column="@p__linq__16" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" />
<ColumnReference Column="@p__linq__15" ParameterCompiledValue="N'ABCD4'" ParameterRuntimeValue="N'ABCD4'" />
<ColumnReference Column="@p__linq__14" ParameterCompiledValue="(10776)" ParameterRuntimeValue="(10776)" />
<ColumnReference Column="@p__linq__13" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" />
<ColumnReference Column="@p__linq__12" ParameterCompiledValue="(0)" ParameterRuntimeValue="(0)" />
<ColumnReference Column="@p__linq__11" ParameterCompiledValue="N'ABCD4'" ParameterRuntimeValue="N'ABCD4'" />
<ColumnReference Column="@p__linq__10" ParameterCompiledValue="N'ABCD4'" ParameterRuntimeValue="N'ABCD4'" />
<ColumnReference Column="@p__linq__9" ParameterCompiledValue="NULL" ParameterRuntimeValue="NULL" />
<ColumnReference Column="@p__linq__8" ParameterCompiledValue="NULL" ParameterRuntimeValue="NULL" />
<ColumnReference Column="@p__linq__7" ParameterCompiledValue="NULL" ParameterRuntimeValue="NULL" />
<ColumnReference Column="@p__linq__6" ParameterCompiledValue="N'ABCD4'" ParameterRuntimeValue="N'ABCD4'" />
<ColumnReference Column="@p__linq__5" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" />
<ColumnReference Column="@p__linq__4" ParameterCompiledValue="(513)" ParameterRuntimeValue="(513)" />
<ColumnReference Column="@p__linq__3" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" />
<ColumnReference Column="@p__linq__2" ParameterCompiledValue="(513)" ParameterRuntimeValue="(513)" />
<ColumnReference Column="@p__linq__1" ParameterCompiledValue="(8)" ParameterRuntimeValue="(8)" />
<ColumnReference Column="@p__linq__0" ParameterCompiledValue="(513)" ParameterRuntimeValue="(513)" />
</ParameterList>
Rather it looks as though you are benefitting from The Parameter Embedding Optimization.
The query text is cut off in the plan but I can see places where you are comparing parameters with literals. Perhaps this is a catch all query

When you use OPTION (RECOMPILE)
the plan compiled only has to work for the passed parameter values. SQL Server can look at the value of the parameters passed and effectively replace the highlighted expressions with TRUE
or FALSE
.
This potentially allows it to simplify out whole branches of the plan if they are not relevant to the parameter values being passed.
A simple example of this would be
EXEC sys.sp_executesql
N'SELECT * FROM master..spt_values WHERE @Param <> 0 OPTION (RECOMPILE)',
N'@Param INT',
@Param = 0;
The plan is compiled when @Param=0
and it only has to be correct for this value so the @Param <> 0
can be evaluated at compile time as false
and the plan doesn't access the table at all.

Without the OPTION (RECOMPILE)
you see this
EXEC sys.sp_executesql
N'SELECT * FROM master..spt_values WHERE @Param <> 0',
N'@Param INT',
@Param = 0;

Even though the sniffed parameter value and the runtime parameter value are the same the plan cannot be optimised to the same extent as it will be cached and still need to work if passed a different parameter value.