Select points falling outside of buffer and count

Joining on ST_DWithin is correct, as this is fast assuming you have appropriate spatial indices. However, you want to use, in pseudo code, a RIGHT JOIN ... WHERE injuries IS NULL type syntax, to find all those injuries that took place more than 15 metres from a bike route. (Equally, this could be written as a LEFT JOIN WHERE somthing IS NULL query, the point being, that this is how you find elements of one table that do not appear when joined on another table). Once you have those accident geometries, more than 15m from a bike route, you can use ST_Intersects to join on the boroughs table and do a group by/count.

So, without testing, something like:

WITH injuries_outside_bikelanes (geom) AS 
 SELECT 
   inj.id, inj.geom 
   FROM injuries_2263 inj 
      RIGHT JOIN bike_routes_2015 bik ON ST_DWithin(inj.geom, bik.geom, 15) 
  WHERE inj.id IS NULL
 )
 SELECT 
      bo.*, count(inj.id)
  FROM  nyc_cd_2263 bo, injuries_outside_bikelanes inj
 WHERE ST_Intersects(bo.geom, inj.geom) 
 GROUP BY bo.gid;

It is always worth running an EXPLAIN on your queries to ensure that indices are being used correctly. If you have spatial indices on all the geometry columns here, you should see two index scans on spatial indices come back from the explain statement. If you don't, this will probably explain your timing issues.