diff --git a/core/lib/Drupal/Component/Utility/SafeMarkup.php b/core/lib/Drupal/Component/Utility/SafeMarkup.php
index a3f2d6818f..3bc8b4bc07 100644
--- a/core/lib/Drupal/Component/Utility/SafeMarkup.php
+++ b/core/lib/Drupal/Component/Utility/SafeMarkup.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Component\Utility;
 
+@trigger_error(__NAMESPACE__ . '\SafeMarkup will be removed before Drupal 9.0.0. Use the appropriate sanitization functions or the theme and render systems so that the output can can be themed, escaped, and altered properly. See see https://www.drupal.org/node/2549395', E_USER_DEPRECATED);
+
 use Drupal\Component\Render\HtmlEscapedText;
 use Drupal\Component\Render\FormattableMarkup;
 use Drupal\Component\Render\MarkupInterface;
diff --git a/core/lib/Drupal/Core/Config/Testing/ConfigSchemaChecker.php b/core/lib/Drupal/Core/Config/Testing/ConfigSchemaChecker.php
index ea8e27e414..c40a9adaad 100644
--- a/core/lib/Drupal/Core/Config/Testing/ConfigSchemaChecker.php
+++ b/core/lib/Drupal/Core/Config/Testing/ConfigSchemaChecker.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Core\Config\Testing;
 
+@trigger_error(__NAMESPACE__ . '\ConfigSchemaChecker is deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. Use Drupal\Core\Config\Development\ConfigSchemaChecker. See https://www.drupal.org/node/2828126', E_USER_DEPRECATED);
+
 use Drupal\Core\Config\Development\ConfigSchemaChecker as SchemaChecker;
 
 /**
@@ -17,6 +19,8 @@
  *
  * @deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0.
  *   Use Drupal\Core\Config\Development\ConfigSchemaChecker.
+ *
+ * @see https://www.drupal.org/node/2828126
  */
 class ConfigSchemaChecker extends SchemaChecker {
 }
diff --git a/core/lib/Drupal/Core/Entity/EntityHandlerBase.php b/core/lib/Drupal/Core/Entity/EntityHandlerBase.php
index e2b6e1c483..e6d7336359 100644
--- a/core/lib/Drupal/Core/Entity/EntityHandlerBase.php
+++ b/core/lib/Drupal/Core/Entity/EntityHandlerBase.php
@@ -15,6 +15,9 @@
  *   module handler service for your class.
  *
  * @ingroup entity_api
+ *
+ * @todo Remove usages of this class in
+ *   https://www.drupal.org/project/drupal/issues/2471663
  */
 abstract class EntityHandlerBase {
   use StringTranslationTrait;
diff --git a/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/SelectionBase.php b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/SelectionBase.php
index eacd94bcd9..a3557393b8 100644
--- a/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/SelectionBase.php
+++ b/core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/SelectionBase.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Core\Entity\Plugin\EntityReferenceSelection;
 
+@trigger_error(__NAMESPACE__ . '\SelectionBase is deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0. Use \Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection', E_USER_DEPRECATED);
+
 /**
  * @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
  *   Use \Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection
diff --git a/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php b/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php
index 60fe30f594..b82b7607ac 100644
--- a/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php
+++ b/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Core\StringTranslation;
 
+@trigger_error(__NAMESPACE__ . '\TranslationWrapper is deprecated in Drupal 8.x, will be removed before Drupal 9.0. Use the \Drupal\Core\StringTranslation\TranslatableMarkup class instead.', E_USER_DEPRECATED);
+
 /**
  * Provides translatable string class.
  *
diff --git a/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php
index 6b62705acd..4825783cf8 100644
--- a/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php
+++ b/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\entity_reference;
 
+@trigger_error(__NAMESPACE__ . '\ConfigurableEntityReferenceItem is deprecated in Drupal 8.0.x and will be removed in Drupal 9.0.x. Use \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem instead.', E_USER_DEPRECATED);
+
 use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
 
 /**
diff --git a/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php
index f93790863b..240739ebc1 100644
--- a/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php
+++ b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\quickedit\Access;
 
+@trigger_error(__NAMESPACE__ . '\EditEntityFieldAccessCheck is deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0.', E_USER_DEPRECATED);
+
 /**
  * @deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0.
  */
diff --git a/core/modules/rest/src/LinkManager/LinkManager.php b/core/modules/rest/src/LinkManager/LinkManager.php
index 4586c62ecd..5e8c081235 100644
--- a/core/modules/rest/src/LinkManager/LinkManager.php
+++ b/core/modules/rest/src/LinkManager/LinkManager.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\rest\LinkManager;
 
+@trigger_error(__NAMESPACE__ . '\LinkManager is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has been moved to the hal module. This exists solely for BC. See https://www.drupal.org/node/2830467', E_USER_DEPRECATED);
+
 use Drupal\hal\LinkManager\LinkManager as MovedLinkManager;
 
 /**
diff --git a/core/modules/rest/src/LinkManager/LinkManagerBase.php b/core/modules/rest/src/LinkManager/LinkManagerBase.php
index 85eb7b70a9..4450864e79 100644
--- a/core/modules/rest/src/LinkManager/LinkManagerBase.php
+++ b/core/modules/rest/src/LinkManager/LinkManagerBase.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\rest\LinkManager;
 
+@trigger_error(__NAMESPACE__ . '\LinkManagerBase is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has been moved to the hal module. This exists solely for BC. See https://www.drupal.org/node/2830467', E_USER_DEPRECATED);
+
 use Drupal\hal\LinkManager\LinkManagerBase as MovedLinkManagerBase;
 
 /**
diff --git a/core/modules/rest/src/LinkManager/RelationLinkManager.php b/core/modules/rest/src/LinkManager/RelationLinkManager.php
index 6690e21006..6abd7d8902 100644
--- a/core/modules/rest/src/LinkManager/RelationLinkManager.php
+++ b/core/modules/rest/src/LinkManager/RelationLinkManager.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\rest\LinkManager;
 
+@trigger_error(__NAMESPACE__ . '\RelationLinkManager is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has been moved to the hal module. This exists solely for BC. See https://www.drupal.org/node/2830467', E_USER_DEPRECATED);
+
 use Drupal\hal\LinkManager\RelationLinkManager as MovedLinkRelationManager;
 
 /**
diff --git a/core/modules/rest/src/LinkManager/TypeLinkManager.php b/core/modules/rest/src/LinkManager/TypeLinkManager.php
index 6d7ba03ecf..17cac5d304 100644
--- a/core/modules/rest/src/LinkManager/TypeLinkManager.php
+++ b/core/modules/rest/src/LinkManager/TypeLinkManager.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\rest\LinkManager;
 
+@trigger_error(__NAMESPACE__ . '\TypeLinkManager is deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0. This has been moved to the hal module. This exists solely for BC. See https://www.drupal.org/node/2830467', E_USER_DEPRECATED);
+
 use Drupal\hal\LinkManager\TypeLinkManager as MovedTypeLinkManager;
 
 /**
diff --git a/core/modules/simpletest/src/RouteProvider.php b/core/modules/simpletest/src/RouteProvider.php
index 063c9567c1..3fa6f54b5c 100644
--- a/core/modules/simpletest/src/RouteProvider.php
+++ b/core/modules/simpletest/src/RouteProvider.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\simpletest;
 
+@trigger_error(__NAMESPACE__ . '\RouteProvider is deprecated in 8.6.0 for removal before 9.0.0. Use Drupal\KernelTests\RouteProvider instead. See https://www.drupal.org/node/2943146', E_USER_DEPRECATED);
+
 use Drupal\KernelTests\RouteProvider as CoreRouteProvider;
 
 /**
diff --git a/core/modules/simpletest/src/TestBase.php b/core/modules/simpletest/src/TestBase.php
index 1c7982f07e..3a4ea2aad3 100644
--- a/core/modules/simpletest/src/TestBase.php
+++ b/core/modules/simpletest/src/TestBase.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Test\TestDatabase;
 use Drupal\Core\Test\TestSetupTrait;
 use Drupal\Core\Utility\Error;
+use Drupal\KernelTests\TestServiceProvider;
 use Drupal\Tests\AssertHelperTrait as BaseAssertHelperTrait;
 use Drupal\Tests\ConfigTestTrait;
 use Drupal\Tests\RandomGeneratorTrait;
diff --git a/core/modules/simpletest/src/TestServiceProvider.php b/core/modules/simpletest/src/TestServiceProvider.php
index 151260c59d..6b6935c266 100644
--- a/core/modules/simpletest/src/TestServiceProvider.php
+++ b/core/modules/simpletest/src/TestServiceProvider.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\simpletest;
 
+@trigger_error(__NAMESPACE__ . '\TestServiceProvider is deprecated in 8.6.0 for removal before Drupal 9.0.0. Use Drupal\KernelTests\TestServiceProvider instead. See https://www.drupal.org/node/2943146', E_USER_DEPRECATED);
+
 use Drupal\KernelTests\TestServiceProvider as CoreTestServiceProvider;
 
 /**
diff --git a/core/modules/simpletest/src/WebAssert.php b/core/modules/simpletest/src/WebAssert.php
index 04b519203b..e7415163d6 100644
--- a/core/modules/simpletest/src/WebAssert.php
+++ b/core/modules/simpletest/src/WebAssert.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\simpletest;
 
+@trigger_error(__NAMESPACE__ . '\WebAssert is deprecated in Drupal 8.1.1 will be removed before 9.0.0. This was moved to another namespace.', E_USER_DEPRECATED);
+
 use Drupal\Tests\WebAssert as BaseWebAssert;
 
 /**
diff --git a/core/tests/FindDeprecatedTest.php b/core/tests/FindDeprecatedTest.php
new file mode 100644
index 0000000000..7a91c0d37c
--- /dev/null
+++ b/core/tests/FindDeprecatedTest.php
@@ -0,0 +1,115 @@
+<?php
+
+namespace Drupal\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Finder\Finder;
+
+/**
+ * Let's find deprecated classes with no @trigger_error().
+ *
+ * Test requires files which could cause autoloading of other files, so each
+ * test method should be isolated.
+ * @runTestsInSeparateProcesses
+ *
+ * @group deprecation
+ */
+class FindDeprecatedTest extends TestCase {
+
+  protected static $classesToSkip = [
+    // https://www.drupal.org/project/drupal/issues/2471663
+    'Drupal\Core\Entity\EntityHandlerBase',
+    // TODO: Needs followup.
+    'Drupal\Core\Messenger\LegacyMessenger',
+    // https://www.drupal.org/project/drupal/issues/3009848
+    'Drupal\workflows\WorkflowDeleteAccessCheck',
+    // Triggers error in constructor.
+    'Drupal\media\Form\MediaDeleteMultipleConfirmForm',
+    // https://www.drupal.org/project/drupal/issues/3009854
+    'Drupal\hal\Normalizer\FileEntityNormalizer',
+  ];
+
+  protected $currentFile;
+  protected $errorFile;
+
+  public function providePhpFiles() {
+
+    $finder = new Finder();
+    $finder
+      ->in(dirname(__DIR__) . '/lib')
+      ->in(dirname(__DIR__) . '/modules/*/src')
+      ->files()->name('*.php');
+
+    $data = [];
+    foreach ($finder as $file) {
+      $data[] = [$file->getPathname()];
+    }
+    return $data;
+  }
+
+  /**
+   *
+   * @dataProvider providePhpFiles
+   */
+  public function testEachFile($file) {
+    // Communicate with the error handler.
+    $this->errorFile = '';
+    $this->currentFile = $file;
+
+    $this->assertFileExists($file);
+
+    $before = get_declared_classes();
+    set_error_handler([$this, 'errorHandler'], E_USER_DEPRECATED);
+    require $file;
+    set_error_handler(NULL);
+    $loaded = array_diff(get_declared_classes(), $before);
+
+    $class = '';
+
+    if (!empty($loaded)) {
+      // Did we load a class that resembles our file?
+      // This will break if classes only differ by namespace.
+      $file_name = basename($file, '.php');
+
+      foreach ($loaded as $loadee) {
+        $loaded_class = explode("\\", $loadee);
+        if (array_pop($loaded_class) == $file_name) {
+          $class = $loadee;
+        }
+      }
+
+      if ($class) {
+        if (in_array($class, static::$classesToSkip)) {
+          return;
+        }
+        $ref_class = new \ReflectionClass($class);
+        $annotation = $ref_class->getDocComment();
+        if (strpos($annotation, '* @deprecated') !== FALSE) {
+          // Deprecated plugins are a special case. They call @trigger_error()
+          // from their constructor.
+          if (in_array('Plugin', $loaded_class)) {
+            $this->markTestIncomplete('Investigate this plugin file: ' . $file);
+            return;
+          }
+          // This will fail if the error handler did not set errorFile.
+          $this->assertEquals($file, $this->errorFile);
+        }
+      }
+    }
+  }
+
+  public function errorHandler($errno , $errstr, $errfile) {
+    // Only report for unsilenced errors.
+    if (error_reporting() === 0) {
+      // If a class uses a deprecated trait or interface, we don't want to
+      // report that file's @trigger_error().
+      if ($errfile == $this->currentFile) {
+        // Handle @trigger_error() by storing the file that threw the error.
+        $this->errorFile = $errfile;
+        return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
+}
