Can't help the engine to choose the correct execution plan
From your plans I see the problem in this statement:

INSERT INTO #Analysis_ClientAccess_SurveyInstances_SurveyInstances ([SurveyInstanceID]) 
select SI.[SurveyInstanceID] 
from [dbo].[SurveyInstances] SI 
    inner JOIN #Analysis_ClientAccess_SurveyInstances_ProtoSurveysFiltered PSF 
        on SI.[ProtoSurveyID] = PSF.[ProtoSurveyID] 
    inner JOIN #Analysis_ClientAccess_SurveyInstances_ClientAccessStatusIDs CAS 
        on SI.[ClientAccessStatusID] = CAS.[ClientAccessStatusID] 
    inner JOIN #Analysis_ClientAccess_SurveyInstances_CampaignsFiltered CF 
        on SI.[CampaignID] = CF.[CampaignID] 
where SI.[IsOkForExport] = 1 AND SI.[HoldExport] = 0 AND ( PSF.[AllowedBy] = 'C' )
option(RECOMPILE)


There is no need in recompile here since there is no parameters at all, you have only constants here.
The difference in two plans is in the JOIN ORDER:



The correct join order is first

[dbo].[SurveyInstances] SI 
    inner JOIN #Analysis_ClientAccess_SurveyInstances_ProtoSurveysFiltered PSF 
        on SI.[ProtoSurveyID] = PSF.[ProtoSurveyID]


and then everything else, this join applies all the filters and produces only 104 rows that go to final resultset.

Your "slow" plan shows different join order: 

[dbo].[SurveyInstances] SI 
    inner JOIN #Analysis_ClientAccess_SurveyInstances_CampaignsFiltered CF 
        on SI.[CampaignID] = CF.[CampaignID] 


that produces 17 mln of rows.

You don't want this join order so your choices are to use FORCE ORDER hint or to simply save the result of the correct join to another temp table and then to join it with the rest of your query:

select SI.[SurveyInstanceID] 
into #si_psf
from [dbo].[SurveyInstances] SI 
    inner JOIN #Analysis_ClientAccess_SurveyInstances_ProtoSurveysFiltered PSF 
        on SI.[ProtoSurveyID] = PSF.[ProtoSurveyID] 
where SI.[IsOkForExport] = 1 AND SI.[HoldExport] = 0 AND ( PSF.[AllowedBy] = 'C' );


INSERT INTO #Analysis_ClientAccess_SurveyInstances_SurveyInstances ([SurveyInstanceID]) 
select SI.[SurveyInstanceID] 
from #si_psf SI
    inner JOIN #Analysis_ClientAccess_SurveyInstances_ClientAccessStatusIDs CAS 
        on SI.[ClientAccessStatusID] = CAS.[ClientAccessStatusID] 
    inner JOIN #Analysis_ClientAccess_SurveyInstances_CampaignsFiltered CF 
        on SI.[CampaignID] = CF.[CampaignID]; 


I suggest you to use the second method.