You could do that by implementing a jsLink validation for the field. Use the basic jsLink approach to render the default form and apply another validation function to check the other list.
Here's a basic approach for that:
//check if we need jsLink
if (window.SPClientTemplates) {
(function (_) {
'use strict';
function renderTextField(ctx, defaultRender) {
//get the form context - it contains a lot of useful stuff and there are some events we need to define to ensure everything is working
var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(ctx);
//build Custom ValidatorSet
var customValidator = function () {
customValidator.prototype.Validate = function (value) {
var isError = false;
var errorMessage = '';
//do some synchronous jsom to check whatever you want (check this http://www.sharepointnadeem.com/2014/10/sharepoint-using-deferredspromises-or.html)
if (value.indexOf('A') === -1) {
isError = true;
errorMessage = 'The Value must contain an "A".';
}
return new SPClientForms.ClientValidation.ValidationResult(isError, errorMessage);
};
};
//set validator
var validators = new SPClientForms.ClientValidation.ValidatorSet();
validators.RegisterValidator(new customValidator());
formCtx.registerClientValidator(formCtx.fieldName, validators);
//get default HTML/Events
var defaultHtml = defaultRender(ctx);
return defaultHtml;
}
function register() {
var jsLink = {
Templates: {
Fields: {}
}
};
jsLink.Templates.Fields['Text'] = { //use your internal fieldname here or all fields of type "Text" are modified
//'View': function(ctx){ return RenderFieldValueDefault(ctx);},
//'DisplayForm': function(ctx) { return SPField_FormDisplay_Default(ctx)},
'EditForm': function (ctx) { return renderTextField(ctx, SPFieldText_Edit); },
'NewForm': function (ctx) { return renderTextField(ctx, SPFieldText_Edit); }
};
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(jsLink);
}
ExecuteOrDelayUntilScriptLoaded(register, 'clienttemplates.js');
})({});
}