So, HLSL is a huge pain in the butt. I did some mucking around and managed to get something working, but not in a way that I like.
I couldn’t get the sampler2d for the textures being passed into the shader to work correctly. Whenever I tried, everything would just start to mess up. It’s extra difficult because MonoGame seems to do some optimizations when it compiles the shaders and this makes debugging difficult. I might play around with this a bit more later, but hopefully someone with more shader experience will have some input!
So instead, I tried a different approach. Instead of using the textures and associated samplers, I figured putting the palette into float4 arrays would work. This was a huge pain to get working because the compiler again spewed errors. First my loops were too large, and then second, I was using too many instructions… even though I can’t for the life of me figure out why. I’ve certainly written more complex shaders in XNA before.
Anyway, I pared it down to this… which seems to do what you want, but it’s pretty specialized. I suspect there’s a better solution here and I think your approach using textures might be more “shader friendly”. I’m gonna keep playing around, but here’s something that works at least 
#if OPENGL
#define SV_POSITION POSITION
#define VS_SHADERMODEL vs_3_0
#define PS_SHADERMODEL ps_3_0
#else
#define VS_SHADERMODEL vs_4_0_level_9_1
#define PS_SHADERMODEL ps_4_0_level_9_1
#endif
sampler2D InputSampler = sampler_state
{
	Texture = <SpriteTexture>;
};
float4 xSourcePal[4];
float4 xTargetPal[4];
struct VertexShaderOutput
{
	float4 Position : SV_POSITION;
	float4 Color : COLOR0;
	float2 UV : TEXCOORD0;
};
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
	float4 cIn = tex2D(InputSampler, input.UV) * input.Color;
	float4 cOut = cIn;
	for (int i = 0; i < 4; i++)
	{
		if (xSourcePal[i].r == cIn.r && xSourcePal[i].g == cIn.g && xSourcePal[i].b == cIn.b)
		{
			cOut = xTargetPal[i];
			break;
		}
	}
	return cOut;
}
technique Technique1
{
	pass Pass1
	{
		PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
	}
}
Game1.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace RecolourTest
{
    /// <summary>
    /// This is the main type for your game.
    /// </summary>
    public class Game1 : Game
    {
        GraphicsDeviceManager _graphics;
        SpriteBatch _spriteBatch;
        RenderTarget2D _target;
        Texture2D _train;
        Texture2D _sourcePal;
        Texture2D _targetPal;
        Vector4[] _sourcePalData;
        Vector4[] _targetPalData;
        Effect _effect;
        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            this.IsMouseVisible = true;
        }
        protected override void Initialize()
        {
            base.Initialize();
        }
        protected override void LoadContent()
        {
            _spriteBatch = new SpriteBatch(GraphicsDevice);
            _target = new RenderTarget2D(_graphics.GraphicsDevice, _graphics.PreferredBackBufferWidth, _graphics.PreferredBackBufferHeight);
            _train = this.Content.Load<Texture2D>("train");
            _sourcePal = this.Content.Load<Texture2D>("source_pal");
            _targetPal = this.Content.Load<Texture2D>("target_pal");
            _effect = this.Content.Load<Effect>("RecolourEffect");
            Color[] sourceData = new Color[_sourcePal.Width * _sourcePal.Height];
            _sourcePal.GetData<Color>(sourceData);
            _sourcePalData = new Vector4[sourceData.Length];
            for (int i = 0; i < sourceData.Length; i++)
                _sourcePalData[i] = sourceData[i].ToVector4();
            Color[] targetData = new Color[_targetPal.Width * _targetPal.Height];
            _targetPal.GetData<Color>(targetData);
            _targetPalData = new Vector4[targetData.Length];
            for (int i = 0; i < targetData.Length; i++)
                _targetPalData[i] = targetData[i].ToVector4();
        }
        protected override void UnloadContent()
        {
        }
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();
            base.Update(gameTime);
        }
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            _graphics.GraphicsDevice.SetRenderTarget(_target);
            _graphics.GraphicsDevice.Clear(Color.Transparent);
            _spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp);
            _spriteBatch.Draw(_train, new Vector2(10, 10), Color.White);
            _spriteBatch.Draw(_sourcePal, new Vector2(10 + _train.Width + 10, 10), Color.White);
            _spriteBatch.Draw(_targetPal, new Vector2(10 + _train.Width + 10, 10 + _sourcePal.Height + 10), Color.White);
            _spriteBatch.End();
            _spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null, _effect, null);
            _effect.Parameters["xSourcePal"].SetValue(_sourcePalData);
            _effect.Parameters["xTargetPal"].SetValue(_targetPalData);
            _effect.CurrentTechnique.Passes[0].Apply();
            _spriteBatch.Draw(_train, new Vector2(10, 10 + _train.Height + 10), Color.White);
            _spriteBatch.End();
            float scale = 4f;
            _graphics.GraphicsDevice.SetRenderTarget(null);
            _graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
            _spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp);
            _spriteBatch.Draw(_target, Vector2.Zero, null, Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, 0f);
            _spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}
(Set up your content project as required)